
#ifndef _MD5_H_
#define _MD5_H_

#include "kxdefine.h"
#ifdef __cplusplus
extern "C" {
#endif

typedef struct
{
	kx_s32 iBlockUsed;
	kx_u8 iBlock[64];
	kx_u32 iH[4];
	kx_u32 iLength;
	kx_s8 digest[16];
} MD5_CTX;

struct _tag_mem_stream;
typedef kx_void (*mem_stream_read)(struct _tag_mem_stream* stream, kx_void* buffer, kx_s32 len);
	
typedef struct _tag_mem_stream
{
	mem_stream_read read;
	kx_s32 len;
}
MD5_STREAM;

kx_void MD5Init(MD5_CTX* mdContext);
kx_void MD5Update(MD5_CTX* mdContext, const kx_s8 *aBuffer, kx_s32 aLength);
kx_void MD5UpdateStream(MD5_CTX* mdContext, MD5_STREAM* stream);
kx_void MD5Final(MD5_CTX* mdContext);

kx_bool md5_encode_str(kx_s8* buffer, const kx_s8 *string);
kx_bool md5_encode_str_bin(kx_s8* buffer, const kx_u8 *bin, kx_s32 len);
kx_bool md5_encode_stream_str(kx_s8* buffer, MD5_STREAM *string);

kx_bool md5_encode_bin(kx_u8* buffer, const kx_u8 *bin, kx_s32 len);
kx_bool md5_encode_stream_bin(kx_u8* buffer, MD5_STREAM *string);
	
//the following is one impelement of MD5_STREAM
//eg. str1 = "aaa" str2 = ":ef" str3 = "456"
//if we need to md5 str1+str2+str3=======>MD5("aaa:ef456")
//we should build code as following..!!!!!!!!!we don't need to alloc new memory buffer
//		kx_s8 md5_buffer[33];//==========>receive md5 result
//		KX_MD5_STREAM1 temp = {0};
//		const kx_s8* argv[3];
//		kx_s32* arg_len[3];
//		argv[0] = str1; argv[1] = str2; argv[2] = str3;
//		arg_len[0] = strlen(str1); arg_len[1]= strlen(str2); arg_len[2] = strlen(str3);
//		temp.argc = 3;//=======>str1,str2,str3,  3 part of strings
//		temp.arg_len = arg_len;
//		temp.argv = argv;
//		temp.pos_arg = 0;//must be 0 initlize
//		temp.index_arg = 0;//must be 0 initlize
//		temp.stream.read = kx_md5_stream_read;//must be kx_md5_stream_read initlize
//		temp.stream.len = strlen(str1)+strlen(str2)=strlen(str3);//must be total size of 3 part initlize
//		md5_encode_stream(md5_buffer, &temp.stream);//md5 compute
typedef struct
{
	MD5_STREAM stream;
	kx_s32 argc;
	kx_s32* arg_len;
	const kx_s8** argv;
	kx_s32 index_arg;
	kx_s32 pos_arg;
}
KX_MD5_STREAM1;
kx_void kx_md5_stream_read(MD5_STREAM* stream, kx_void* buffer, kx_s32 len);
#ifdef __cplusplus
}
#endif
#endif
